package com.comm.features.learn.test.config;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.logging.Logger;

/**
 *  aop controller层的日志管理
 *  若有多个aop需要处理，则可以通过 @Order 来指定执行的优先级
 *      在切入点前的操作，按order的值由小到大执行
 *      在切入点后的操作，按order的值由大到小执行
 */
//@Order(1)
@Aspect
@Component
public class AopConfig {

    private Logger logger = Logger.getLogger(this.getClass().getName());

    // 因为定义变量会有同步的问题，所以引入了ThreadLocal来让Before和AfterReturning来进行访问
    ThreadLocal<Long> startTime = new ThreadLocal<Long>();

    @Pointcut("execution(public * com.comm.features.learn.test.controller.*.*(..))")
    public void controllerLog(){

    }

    @Before("controllerLog()")
    public void doBefore(JoinPoint joinPoint){

        startTime.set(System.currentTimeMillis());

        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();

        HttpServletRequest request = attributes.getRequest();

        logger.info("AOP LOG BEFORE BEGIN----------------------------------------------");
        // 请求的url
        logger.info("url:" + request.getRequestURI().toString());
        // 请求的方法，get、post等
        logger.info("HTTP_METHOD:" + request.getMethod());
        // 请求的ip地址
        logger.info("IP:" + request.getRemoteAddr());
        // 请求的方法的整个包名
        logger.info("CLASS_METHOD:"  + joinPoint.getSignature());
        // 请求的方法的参数
        logger.info("ARGS:" + Arrays.toString(joinPoint.getArgs()));
        logger.info("AOP LOG BEFORE END----------------------------------------------");
    }

    @AfterReturning(returning = "ret",pointcut = "controllerLog()")
    public void doAfterReturning(Object ret){
        logger.info("doAfterReturning:" + ret);
        logger.info("执行时间：" + (System.currentTimeMillis() - startTime.get()) + "ms");
    }

}
